#include "EventEntry.h"

#include "EventAddDialog.h"

#include <libintl.h>
#define _(String) gettext(String)

/* EventEntry 对象的信号 */
static guint entry_signal[EVENT_ENTRY_SIGNAL_END];

struct _EventEntry
{
	AdwBin parent_instance;
	//
	GtkLabel *event_name;
	GtkLabel *event_describe;
	GtkLabel *event_end_time;
	GtkLabel *group_name;
	GtkFrame *motion_frame;
	//
	GtkGesture *mouse_clicker;
	//
	time_t	end_time;
	euint32 group_id;
	euint32 event_id;
	bool	can_modify;
	bool	is_important;
};

G_DEFINE_FINAL_TYPE(EventEntry, event_entry, ADW_TYPE_BIN)

static void
event_entry_finalize(GObject *object)
{
	g_object_unref(EVENT_ENTRY(object)->mouse_clicker);
	G_OBJECT_CLASS(event_entry_parent_class)->finalize(object);
}

static void
event_entry_class_init(EventEntryClass *klass)
{
	GObjectClass   *object_class = G_OBJECT_CLASS(klass);
	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);

	gtk_widget_class_set_template_from_resource(
		widget_class, "/org/korack/event/ui/EventEntry.ui");
	gtk_widget_class_bind_template_child(widget_class, EventEntry,
					     event_name);
	gtk_widget_class_bind_template_child(widget_class, EventEntry,
					     event_describe);
	gtk_widget_class_bind_template_child(widget_class, EventEntry,
					     event_end_time);
	gtk_widget_class_bind_template_child(widget_class, EventEntry,
					     group_name);
	gtk_widget_class_bind_template_child(widget_class, EventEntry,
					     motion_frame);

	entry_signal[EVENT_ENTRY_SIGNAL_REMOVE] = g_signal_newv(
		"remove-entry", G_TYPE_FROM_CLASS(object_class),
		G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
		NULL, NULL, NULL, NULL, G_TYPE_NONE, 0, NULL);

	entry_signal[EVENT_ENTRY_SIGNAL_MODIFY] = g_signal_newv(
		"entry-modify", G_TYPE_FROM_CLASS(object_class),
		G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
		NULL, NULL, NULL, NULL, G_TYPE_NONE, 0, NULL);

	object_class->finalize = event_entry_finalize;
}

static void
entry_single_click(EventEntry *self, gpointer data)
{
	EventAddDialog *add_dialog;
	g_return_if_fail(self != NULL);
	if (!self->can_modify)
		return;
	add_dialog = event_add_dialog_new();
	event_add_dialog_set_default_template(add_dialog, self);

	adw_dialog_present(ADW_DIALOG(add_dialog), GTK_WIDGET(self));
}

static void
event_entry_init(EventEntry *self)
{
	gtk_widget_init_template(GTK_WIDGET(self));
	self->end_time	   = 0;
	self->can_modify   = false;
	self->event_id	   = 0;
	self->group_id	   = 0;
	self->is_important = false;
	/* 鼠标单击 */
	self->mouse_clicker = gtk_gesture_click_new();
	gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(self->mouse_clicker),
				      1);
	gtk_widget_add_controller(GTK_WIDGET(self),
				  GTK_EVENT_CONTROLLER(self->mouse_clicker));
	g_signal_connect_swapped(self->mouse_clicker, "released",
				 G_CALLBACK(entry_single_click), self);
}

GtkWidget *
event_entry_new(void)
{
	return g_object_new(EVENT_TYPE_ENTRY, NULL);
}

void
event_entry_set_event_name(EventEntry *self, const char *event_name)
{
	g_return_if_fail(self != NULL);
	gtk_label_set_label(self->event_name, event_name);
}

void
event_entry_set_event_describe(EventEntry *self, const char *event_describe)
{
	g_return_if_fail(self != NULL);
	gtk_label_set_label(self->event_describe, event_describe);
}

void
event_entry_set_group_name(EventEntry *self, const char *group_name)
{
	g_return_if_fail(self != NULL);
	gtk_label_set_label(self->group_name, group_name);
}

void
event_entry_set_group_id(EventEntry *self, euint32 group_id)
{
	g_return_if_fail(self != NULL);
	self->group_id = group_id;
}

void
event_entry_set_event_id(EventEntry *self, euint32 event_id)
{
	g_return_if_fail(self != NULL);
	self->event_id = event_id;
}

void
event_entry_set_end_time(EventEntry *self, time_t end_time)
{
	struct tm  *time_info;
	static char buffer[50];
	g_return_if_fail(self != NULL);
	self->end_time = end_time;
	time_info      = localtime(&end_time);
	sprintf(buffer, "%04d-%02d-%02d", (time_info->tm_year + 1900),
		(time_info->tm_mon + 1), (time_info->tm_mday));
	gtk_label_set_label(self->event_end_time, buffer);
}

void
event_entry_set_can_modify(EventEntry *self, bool can_modify)
{
	g_return_if_fail(self != NULL);
	self->can_modify = can_modify;
	if (can_modify) {
		gtk_widget_set_tooltip_text(GTK_WIDGET(self),
					    _("Click to modify event"));
	} else {
		gtk_widget_set_tooltip_text(GTK_WIDGET(self),
					    _("Non modifiable events"));
	}
}

void
event_entry_set_is_important(EventEntry *self, bool is_important)
{
	static const char *css_normal[]	   = { "title-3", "title-color-normal",
					       NULL },
			  *css_important[] = { "title-3",
					       "title-color-important", NULL };
	g_return_if_fail(self != NULL);
	self->is_important = is_important;
	gtk_widget_set_css_classes(GTK_WIDGET(self->event_name),
				   (is_important ? css_important : css_normal));
}

const char *
event_entry_get_event_name(EventEntry *self)
{
	g_return_val_if_fail(self, NULL);
	return gtk_label_get_label(self->event_name);
}

const char *
event_entry_get_group_name(EventEntry *self)
{
	g_return_val_if_fail(self, NULL);
	return gtk_label_get_label(self->group_name);
}

const char *
event_entry_get_event_describe(EventEntry *self)
{
	g_return_val_if_fail(self, NULL);
	return gtk_label_get_label(self->event_describe);
}

euint32
event_entry_get_group_id(EventEntry *self)
{
	g_return_val_if_fail(self, 0);
	return self->group_id;
}

euint32
event_entry_get_event_id(EventEntry *self)
{
	g_return_val_if_fail(self, 0);
	return self->event_id;
}

time_t
event_entry_get_end_time(EventEntry *self)
{
	g_return_val_if_fail(self, 0L);
	return self->end_time;
}

bool
event_entry_get_is_important(EventEntry *self)
{
	g_return_val_if_fail(self, false);
	return self->is_important;
}

bool
event_entry_compare_time(const EventEntry *entry1, const EventEntry *entry2)
{
	g_return_val_if_fail(entry1 != NULL && entry2 != NULL, false);
	return entry1->end_time > entry2->end_time;
}

void
event_entry_emit_signal(EventEntry *self, EventEntrySignal e_signal)
{
	g_return_if_fail(self != NULL);
	g_signal_emit(self, entry_signal[e_signal], 0);
}
